package org.richin.file.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.GZIPOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.richin.io.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZipUtils {
	
	protected static Logger log = LoggerFactory.getLogger(ZipUtils.class);
    private byte[] gzip(byte[] data) {
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);
        GZIPOutputStream output = null;
        try {
            output = new GZIPOutputStream(byteOutput);
            output.write(data);
        }
        catch (IOException e) {}
        finally {
            if(output!=null) {
                try {
                    output.close();
                }
                catch (IOException e) {}
            }
        }
        return byteOutput.toByteArray();
    }
	/**   
	
	 * 压缩文件   
	
	 * @param inputFileName 要压缩的文件或文件夹路径，例如：c:\\a.txt,c:\\a\   
	
	 * @param outputFileName 输出zip文件的路径，例如：c:\\a.zip   
	
	 */

	public static void zip(String inputFileName, String outputFileName){

		ZipOutputStream out = null;
		try {
			out = new ZipOutputStream(new FileOutputStream(outputFileName));
			zip(out, new java.io.File(inputFileName), "");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {

            IOUtils.close(out);
        }


	}
	/**
     * 将一个目录进行压缩
     *
     * @param toCompressDir 要压缩的目录
     * @param outputFile 压缩后的文件(zip格式)
     */
    public static void zip(File toCompressDir, File outputFile) {
            ZipOutputStream out = null;
            try {
                    out = new ZipOutputStream(new FileOutputStream(outputFile));
                    zip(out, toCompressDir, "");
            } catch (FileNotFoundException e) {
                    return;
            } catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
                    IOUtils.close(out);
            }
    }

	/**   
	
	 * 压缩文件   
	
	 * @param out org.apache.tools.zip.ZipOutputStream   
	
	 * @param file 待压缩的文件   
	
	 * @param base 压缩的根目录   
	
	 */

	private static void zip(ZipOutputStream out, File file, String base) throws Exception {

		if (file.isDirectory()) {

			File[] fl = file.listFiles();

			base = base.length() == 0 ? "" : base + File.separator;

			for (int i = 0; i < fl.length; i++) {

				zip(out, fl[i], base + fl[i].getName());

			}

		} else {

			out.putNextEntry(new ZipEntry(base));

			log.debug("添加压缩文件：" + base);

			FileInputStream in = new FileInputStream(file);

			int b;

			while ((b = in.read()) != -1) {

				out.write(b);

			}

			in.close();

		}

	}

	/**   
	
	 * 解压zip文件   
	
	 * @param zipFileName 待解压的zip文件路径，例如：c:\\a.zip   
	
	 * @param outputDirectory 解压目标文件夹,例如：c:\\a\   
	
	 */

	public static void unZip(String zipFileName, String outputDirectory) throws Exception {

		ZipFile zipFile = new ZipFile(zipFileName);

		try {

			Enumeration<?> e = zipFile.getEntries();

			ZipEntry zipEntry = null;

			createDirectory(outputDirectory, "");

			while (e.hasMoreElements()) {

				zipEntry = (ZipEntry) e.nextElement();

				log.debug("解压：" + zipEntry.getName());

				if (zipEntry.isDirectory()) {

					String name = zipEntry.getName();

					name = name.substring(0, name.length() - 1);

					File f = new File(outputDirectory + File.separator + name);

					f.mkdir();

					log.debug("创建目录：" + outputDirectory + File.separator + name);

				} else {

					String fileName = zipEntry.getName();

					fileName = fileName.replace('\\', '/');

					if (fileName.indexOf("/") != -1) {

						createDirectory(outputDirectory, fileName.substring(0, fileName.lastIndexOf("/")));

						fileName = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());

					}

					File f = new File(outputDirectory + File.separator + zipEntry.getName());

					f.createNewFile();

					InputStream in = zipFile.getInputStream(zipEntry);

					FileOutputStream out = new FileOutputStream(f);

					byte[] by = new byte[1024];

					int c;

					while ((c = in.read(by)) != -1) {

						out.write(by, 0, c);

					}

					in.close();

					out.close();

				}

			}

		} catch (Exception ex) {

			System.out.println(ex.getMessage());

		} finally {

			zipFile.close();

			log.debug("解压完成！");

		}

	}
	private static void createDirectory(String directory, String subDirectory) {    
		   
		   
		   
        String dir[];    
   
        File fl = new File(directory);    
   
        try {    
   
            if (subDirectory == "" && fl.exists() != true) {    
   
                fl.mkdir();    
   
            } else if (subDirectory != "") {    
   
                dir = subDirectory.replace('\\', '/').split("/");    
   
                for (int i = 0; i < dir.length; i++) {    
   
                    File subFile = new File(directory + File.separator + dir[i]);    
   
                    if (subFile.exists() == false)    
   
                        subFile.mkdir();    
   
                    directory += File.separator + dir[i];    
   
                }    
   
            }    
   
        } catch (Exception ex) {    
   
            System.out.println(ex.getMessage());    
   
        }    
   
    }    

}
